package service

import (
	"log"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/lzppppppp/virapaksa-go/internal/monitor_apply/middleware"
	"github.com/lzppppppp/virapaksa-go/internal/monitor_apply/model"
	"github.com/lzppppppp/virapaksa-go/internal/monitor_apply/repository"
	"github.com/spf13/viper"
	"github.com/xuri/excelize/v2"
)

/*
 * 接收前端post传来的替换监控申请表格
 * 解析表格内容，返回表格数据
 */
func PostReplaceFile(context *gin.Context) {
	file, _ := context.FormFile("file")
	docPath := viper.GetString("document_path") + "/receive/replace/" + file.Filename
	context.SaveUploadedFile(file, docPath)

	// 打开文件
	f, err := excelize.OpenFile(docPath)
	if err != nil {
		log.Printf("ERROR: Open %s file failed", file.Filename)
		context.JSON(500, "ERROR: Open file failed.")
		return
	}
	// sheetName := f.GetSheetName(0)
	ExcelData, err := f.GetRows(f.GetSheetName(0))
	if err != nil {
		log.Printf("ERROR: Open %s first sheet failed", file.Filename)
		context.JSON(500, "ERROR: Open file failed.")
		return
	}

	var jsonData []model.MonitorReplaceApply

	// 文件内容以json格式输出
	for index, row := range ExcelData {

		if index != 0 {
			DB := repository.GetDB()
			var Data []model.CmdbAllServer
			DB.Table("cmdb_all_servers").Where("ip = ?", row[0]).Find(&Data)
			if len(Data) == 0 {
				log.Printf("ERROR: IP %v not found in database.\n", row[0])
				context.JSON(500, "err: ip "+row[0]+" not found")
				return
			}

			cmdbData := Data[0]
			jsonApplyData := model.MonitorReplaceApply{
				ShortName:      cmdbData.ShortName,
				Hostname:       cmdbData.Hostname,
				IP:             row[0],
				Sourcekeywords: row[1],
				Destkeywords:   row[2],
				Datacenter:     cmdbData.Datacenter,
				ServiceName:    cmdbData.SystemName,
				SystemID:       cmdbData.ProjectID,
			}
			jsonData = append(jsonData, jsonApplyData)
		}
	}
	// 返回值
	context.JSON(200, jsonData)
}

/*
 * 接收前端传送过来的替换监控申请数据
 * 解析数据内容生产工单，POST数据
	type receiveDataStruct struct {
		Type string
		Data []model.MonitorReplaceApply
	}
*/
func PostReplaceJsonData(context *gin.Context) {

	// 1. 接收数据
	type receiveDataStruct struct {
		Type string
		Data []model.MonitorReplaceApply
	}
	var param receiveDataStruct

	err := context.BindJSON(&param)
	if err != nil {
		context.JSON(500, gin.H{"err": err})
		return
	}

	DB := repository.GetDB()

	var data []model.MonitorReplaceApply
	var cmdbData []model.CmdbAllServer

	for _, value := range param.Data {
		DB.Table("cmdb_all_servers").Where("ip = ?", value.IP).Find(&cmdbData)
		if len(cmdbData) == 0 {
			log.Printf("ERROR: IP %v not found in database.\n", value.IP)
			context.JSON(500, gin.H{"err": "ip " + value.IP + " not found"})
			return
		}

		cmdbDataFirst := cmdbData[0]
		jsonApplyData := model.MonitorReplaceApply{
			ShortName:      cmdbDataFirst.ShortName,
			Hostname:       cmdbDataFirst.Hostname,
			IP:             value.IP,
			Sourcekeywords: value.Sourcekeywords,
			Destkeywords:   value.Destkeywords,
			AppTeam:        cmdbDataFirst.Datacenter,
			Datacenter:     cmdbDataFirst.Datacenter,
			ServiceName:    cmdbDataFirst.SystemName,
			SystemID:       cmdbDataFirst.ProjectID,
		}
		data = append(data, jsonApplyData)
	}

	// 2. 生成整张单子的流水号
	trackNumberTable := middleware.GenerateOrderNumber("table", "replace", viper.GetString("document_path")+"/countvar/counter_table")
	var typeArr []string

	// 判断表格中有几个不同的系统名
	shortNameTypeArr := make(map[string][]string)
	datacenterTypeArr := make(map[string][]string)

	for _, rowData := range data {

		// 3. 将整张单子存到数据库
		rowData.TrackNumber = trackNumberTable

		if err := DB.Create(&rowData).Error; err != nil {
			log.Printf("ERROR: Save table data to database failed, ip is %v, error is %v", rowData.IP, err)
			context.JSON(500, "IP "+rowData.IP+" save table data to database failed")
			return
		}

		var dataCenter string

		if strings.HasPrefix(rowData.Datacenter, "内蒙") {
			dataCenter = "nm"
		} else if strings.HasPrefix(rowData.Datacenter, "北京") {
			dataCenter = "pek"
		} else if strings.HasPrefix(rowData.Datacenter, "上海") {
			dataCenter = "sh"
		} else if strings.HasPrefix(rowData.Datacenter, "合肥") {
			dataCenter = "hf"
		} else {
			log.Printf("ERROR: Datacenter format error")
			panic("ERROR: Datacenter format error")
		}

		// 4. 判断是否有进程和端口监控，有则存数据库中，注意区分数据中心
		jsonData := model.MonitorReplaceApply{
			ShortName:      rowData.ShortName,
			Hostname:       rowData.Hostname,
			IP:             rowData.IP,
			Sourcekeywords: rowData.Sourcekeywords,
			Destkeywords:   rowData.Destkeywords,
			Datacenter:     dataCenter,
			ServiceName:    rowData.ServiceName,
			SystemID:       rowData.SystemID,
			TrackNumber:    trackNumberTable,
		}

		if param.Type == "process" {

			if err := DB.Table("process_replace_" + jsonData.Datacenter).Create(&jsonData).Error; err != nil {
				log.Printf("ERROR: Create process data failed, data is %v, error is %v", jsonData.IP, err)
				context.JSON(500, "IP "+jsonData.IP+" process monitor data create failed")
				return
			}

			if !middleware.Contains(typeArr, "process") {
				typeArr = append(typeArr, "process")
			}

			if !middleware.Contains(shortNameTypeArr["process"], rowData.ShortName) {
				shortNameTypeArr["process"] = append(shortNameTypeArr["process"], rowData.ShortName)
			}
			if !middleware.Contains(datacenterTypeArr["process"], jsonData.Datacenter) {
				datacenterTypeArr["process"] = append(datacenterTypeArr["process"], jsonData.Datacenter)
			}
		}
		// 判断是否有端口监控，有则数据存库中
		if param.Type == "port" {

			if err := DB.Table("port_replace_" + jsonData.Datacenter).Create(&jsonData).Error; err != nil {
				log.Printf("ERROR: Create port data failed, data is %v, error is %v", jsonData.IP, err)
				context.JSON(500, "IP "+jsonData.IP+" port monitor data create failed")
				return
			}

			if !middleware.Contains(typeArr, "port") {
				typeArr = append(typeArr, "port")
			}

			if !middleware.Contains(shortNameTypeArr["port"], rowData.ShortName) {
				shortNameTypeArr["port"] = append(shortNameTypeArr["port"], rowData.ShortName)
			}
			if !middleware.Contains(datacenterTypeArr["port"], jsonData.Datacenter) {
				datacenterTypeArr["port"] = append(datacenterTypeArr["port"], jsonData.Datacenter)
			}
		}
	}

	// 5. 创建用于部署的单子，存数据库中
	for _, value := range typeArr {
		trackNumberType := middleware.GenerateOrderNumber(value, "replace", viper.GetString("document_path")+"/countvar/counter_"+value)
		deployData := model.ApplyTrackNumber{
			TrackNumber:      trackNumberType,
			ShortName:        strings.Join(shortNameTypeArr[value], "\n"),
			DeployState:      "NotDeployed",
			ServiceState:     "registered",
			TrackNumberTable: trackNumberTable,
		}
		for _, dcValue := range datacenterTypeArr[value] {
			if err := DB.Table(value + "_track_numbers_" + dcValue).Create(&deployData).Error; err != nil {
				log.Printf("ERROR: Create deploy data failed, table number is %v, error is %v", trackNumberTable, err)
				context.JSON(500, "Table number "+trackNumberTable+" data create failed")
				return
			}

		}
	}

	responseData := model.ResponseData{
		Code: 200,
		Msg:  "success",
	}
	context.JSON(200, responseData)
}
